/*
 *  $Id: CreatureCard.cs 1221 2010-11-30 16:54:52Z thenn.erannor $
 *	This file is a part of Ragima CCG.
 *	(C) 2008-2009 Ragima development group.
 *
 *	Licensed under the terms of the GNU GPL License version 2.
 *
 */

using AgateLib.Geometry;

namespace Ragima {
    /// <summary>
    /// Карта существа
    /// Содержит: раса, начальные атака и здоровье, и состояние при призыве
    /// </summary>
    public abstract class CreatureCard: SummonableCard {
        private Race _race;
        public bool AutoDmgType;
        public int Damage;
        public int Health;
        public CreatureState SummonState;

        public CreatureCard(string id): base(id) {
            LogMessage = Resources.Game.SummonCreature;
            Target = SummonTarget.Summon;
            _race = null;
            AutoDmgType = true;
            SummonState = CreatureState.Delay;
        }

        protected override bool Animate {
            get { return true; }
        }

        public override CardType CardType {
            get { return CardType.Creature; }
        }

        public Race Race {
            get { return _race ?? (_race = RaceManager.GetUnique(this)); }
            set { _race = value; }
        }

        public void SetRace<T>() where T: Race, new() {
            _race = RaceManager.GetRace<T>();
        }

        protected override int GetWeight() {
            int weight = base.GetWeight();
            weight += Damage * WeightCoeff.Damage;
            weight += Health * WeightCoeff.Health;
            switch (SummonState) {
                case CreatureState.Tapped:
                    weight += WeightCoeff.SummonAsTapped;
                    break;
                case CreatureState.Untapped:
                    weight += WeightCoeff.SummonAsUntapped;
                    break;
            }
            // TODO: учесть расу, и тип урона
            return weight;
        }

        public override int GetHealth() { return Health; }
        public override int GetDamage() { return Damage; }

        public override void DoAction(TargetArgs args) {
            var sa = args as TargetArgs<int>;
            if (sa != null)
                args.Player.SummonCreature(this, sa.Target);
        }

        public override bool DrawHelp(int x, int y) {
            bool draw = base.DrawHelp(x, y);
            if (draw) DrawParams(x+276, y+294);
            return draw;
        }
        private void DrawParams(int x, int y) {
            string s = string.Format("{0} / {1}", Damage, Health);
            Data.Fonts.Main.Color = Color.Black;
            Data.Fonts.Main.DrawRight(x, y+2, s);
        }

        public override void CollectNaturalAffects(ICollector<Affect> affects) {
            Race.SetNaturalAffects(this, affects);
            base.CollectNaturalAffects(affects);
        }

        public override void CollectAbilities(ICollector<AbilityCard> abilities) {
            Race.SetAbilities(this, abilities);
            base.CollectAbilities(abilities);
        }
    }

    /// <summary>
    /// Генерализованная карта существа, приводящая TargetArgs к определенному типу
    /// </summary>
    public abstract class CreatureCard<T>: CreatureCard {
        public CreatureCard(string id): base(id) {}

        public sealed override void ManaCostAction(TargetArgs args, ElementValues manas) {
            if (args is TargetArgs<T>)
                ManaCostAction((TargetArgs<T>) args, manas);
            else
                base.ManaCostAction(args, manas);
        }
        public sealed override bool IsPossibleAction(TargetArgs args) {
            if (args is TargetArgs<T>)
                return IsPossibleAction((TargetArgs<T>) args);
            else
                return base.IsPossibleAction(args);
        }
        public sealed override void LogAction(Log log, TargetArgs args) {
            if (args is TargetArgs<T>)
                LogAction(log, (TargetArgs<T>) args);
            else
                base.LogAction(log, args);
        }
        public sealed override void DoAction(TargetArgs args) {
            if (args is TargetArgs<T>)
                DoAction((TargetArgs<T>) args);
            else
                base.DoAction(args);
        }

        protected virtual void ManaCostAction(TargetArgs<T> args, ElementValues manas) {
            base.ManaCostAction(args, manas);
        }
        protected virtual bool IsPossibleAction(TargetArgs<T> args) {
            return base.IsPossibleAction(args);
        }
        protected virtual void LogAction(Log log, TargetArgs<T> args) {
            base.LogAction(log, args);
        }
        protected virtual void DoAction(TargetArgs<T> args) {
            base.DoAction(args);
        }
    }
}
